// 设置jqgrid的样式
$.jgrid.defaults.styleUI = 'Bootstrap';

/**
 * 弹出框
 * @type {{open: Dialog.open, openByUrl: Dialog.openByUrl, openUrl: Dialog.openUrl, alert: Dialog.alert, confirm: Dialog.confirm, msg: Dialog.msg}}
 */
var Dialog = {
    /**
     * 打开一个弹出窗口
     * @param title 必须。窗口名称
     * @param content 必须。窗口内容。任意的文本或html或dom元素
     * @param options 可选。其他layer参数
     */
    open: function (title, content, options) {
        options = $.extend({
            type: 1,
            shadeClose: false,
            title: title,
            content: content
        }, options);

        return layer.open(options);
    },
    /**
     * 根据URL打开一个弹出窗口
     * @param title 必须。窗口名称
     * @param url 必须。URL，需返回HTML片段，而不是完整的HTML内容
     * @param options 可选。其他layer参数
     */
    openByUrl: function (title, url, options) {
        $.post(url, {}, function (data) {
            Dialog.open(title, data, options);
        }, 'html');
    },
    /**
     * 打开一个弹出窗口
     * @param title 必须。窗口名称
     * @param url 必须。URL，需返回HTML内容，如果返回的是HTML片段，请使用openByUrl方法
     * @param options 可选。其他layer参数
     */
    openUrl: function (title, url, options) {
        options = $.extend({
            type: 2,
            shadeClose: false,
            title: title,
            content: url
        }, options);

        var index = layer.open(options);
        return index;
    },
    /**
     * 警告框
     * @param message 必须。提示信息
     * @param okFn 可选。点击确定的回调函数
     * @param options 可选。其他layer参数
     */
    alert: function (message, okFn, options) {
        options = $.extend({
            icon: 2,
            title: '系统提示'
        }, options);

        layer.alert(message, options, function (index) {
            if (okFn) {
                okFn();
            }
            layer.close(index);
        });
    },
    /**
     * 操作确认框
     * @param message 必须。提示信息
     * @param okFn 可选。点击确定的回调函数
     * @param cancelFn 可选。点击取消的回调函数
     * @param options 可选。其他layer参数
     */
    confirm: function (message, okFn, cancelFn, options) {
        options = $.extend({
            icon: 3,
            title: '操作提示'
        }, options);
        layer.confirm(message, options,
        	function (index) {
	            if (okFn!=null && okFn!=undefined) {okFn();}
	            layer.close(index);
        	}, function (index) {
	            if (cancelFn!=null && cancelFn!=undefined) {cancelFn();}
	            layer.close(index);
        	}
        );
    },
    /**
     * 提示操作框
     * @param title 必须。提示信息
     * @param content 必须。操作内容
     * @param okFn 可选。确定的的回调函数
     * @param options 可选。其他layer参数
     */
    prompt: function(title, content, okFn, options){
        options = $.extend({
            title: title,
            area: '400px',
            autoClose: true
        }, options);

        return layer.confirm(content, options, function(index){
            if(okFn){
                okFn();
            }
            if(options.autoClose) {
                layer.close(index);
            }
        });
    },
    /**
     * 提示框
     * @param message 必须。提示信息
     * @param endFn 可选。关闭的的回调函数
     * @param options 可选。其他layer参数
     */
    msg: function (message, endFn, options) {
        options = $.extend({
            icon: 1,
            anim: 1,
            time: 1000
        }, options);

        layer.msg(message, options, function () {
            if (endFn) {
                endFn();
            }
        });
    },
    errorMsg: function (message, endFn, options) {
        options = $.extend({
            icon: 2,
            anim: 1,
            time: 2000
        }, options);

        layer.msg(message, options, function () {
            if (endFn) {
                endFn();
            }
        });
    },
    tips: function (message, id, options) {
        options = $.extend({
            tips: [2, '#0FA6D8'],
            tipsMore: false,
            time:2000
        }, options);

        layer.tips(message, "#"+id, options);
    },

    /**
     * 关闭Frame
     * @param frameName window的name
     */
    closeFrame: function (frameName) {
        var index = parent.layer.getFrameIndex(frameName); //获取窗口索引
        parent.layer.close(index);
    },

    /**
     * 设置dialog 宽度
     * @param offset 偏移量
     */
    width: function (fixHeight) {
        if (isNaN(fixHeight)) {
            fixHeight = 0;
        }
        return $(window).width() / 3 - fixHeight;
    },

    /**
     * 设置dialog 高度
     * @param offset
     * @returns {*}
     */
    height: function (fixHeight) {
        if (isNaN(fixHeight)) {
            fixHeight = 0;
        }
        return $(window).height() / 2 + fixHeight;
    }
};

var Page = {

    /**
     * 表单提交初始化方式
     * @param form 表单
     * @param options jqueryValidate参数, submitSuccess: 提交成功回调函数,submitFail：提交失败回调函数
     */
    validateForm: function (form, options) {
        form = $(form);
        options = $.extend({
            highlight: function (element) {
                if ($(element).closest("table").length > 0) {
                    var $this = $(element).closest("td");
                    $this.prev().removeClass("has-success").addClass("has-error");
                    $this.removeClass("has-success").addClass("has-error");
                } else {
                    $(element).closest(".form-group").removeClass("has-success").addClass("has-error");
                }
            },
            success: function (element,r) {
                layer.close($(element).attr("tipsIndex"));
                if ($(element).closest("table").length > 0) {
                    var $this = $(element).closest("td");
                    $this.removeClass("has-error").addClass("has-success");
                    $this.prev().removeClass("has-error").addClass("has-success");
                } else {
                    $(r).closest(".form-group").removeClass("has-error").addClass("has-success");
                }
            },
            errorElement: "span",
            errorPlacement: function (e, r) {
                layer.close($(r).attr("tipsIndex"));
                if (e[0].innerText != ''){
                    $(r).attr("tipsIndex", layer.tips(e.text(), r, {
                        tips: [2, '#ffcc99'],
                        tipsMore: true,
                        // area: ['120px', 'auto'],
                        time: 0
                    }));
                }else{
                    layer.close($(r).attr("tipsIndex"));
                }
            },
            errorClass: "help-block m-b-none",
            validClass: "m-b-none",
            // 默认提交方式
            submitHandler: function (_form) {
                if (form.valid()) {
                    var submitFn = function () {
                        Page.ajaxPOST(form.attr('action'), form.serialize(), options.submitSuccess, {'failFn': options.submitFail});
                    };
                    if (options.tips) { // 有提示信息
                        Dialog.confirm(options.tips, function () {
                            submitFn();
                        });
                    } else {
                        submitFn();
                    }
                }
            },
            // 提交成功
            submitSuccess: function (data) {
                Dialog.msg(data.msg);
            },
            // 提交失败
            submitFail: function (data) {
                Dialog.alert(data.msg ? data.msg : '操作失败！');
            }
        }, options);
        return form.validate(options);
    },


    /**
     * ajax请求
     * @param method 请求方法  GET / POST
     * @param url 请求URL
     * @param data 请求参数
     * @param successFn 成功回调函数
     * @param failFn 失败回调函数
     */
    ajax: function (method, url, data, successFn, options) {
        var ajaxOptions = $.extend({
            contentType: 'application/x-www-form-urlencoded',
            async: true,
            showLoading: false,
            loadingMsg: '加载中…',
            failFn: "",
            processData: true,
            cache: true,
            dataType: 'json'
        }, options);

        if (!Common.isEmpty(options) && !Common.isEmpty(options.loadingMsg)) {
            ajaxOptions.showLoading = true;
        }
        $.ajax({
            url: url,
            type: method,
            data: (Common.isEmpty(data) ? {} : data),
            async: ajaxOptions.async,
            processData: ajaxOptions.processData,
            cache: ajaxOptions.cache,
            contentType: ajaxOptions.contentType,
            dataType: ajaxOptions.dataType,
    	    beforeSend : function() {
                if(ajaxOptions.showLoading) {
                    ajaxLoading(ajaxOptions.loadingMsg);
                }
            },
    	    complete : function(XMLHttpRequest, sessionStatus) {
    	    	closeAjaxLoading();
            },
            success: function (data) {
                if (data.code == "0") {
                    if (successFn && ((typeof successFn) == "function")) {
                        successFn(data);
                    } else {
                        Dialog.msg(data.msg); // 默认
                    }
                } else {
                    if (ajaxOptions.failFn && ((typeof ajaxOptions.failFn) == "function")) {
                        ajaxOptions.failFn(data);
                    } else {
                        Dialog.alert(data.msg); // 默认
                    }
                }
            },
            error: function (r) {
                if (ajaxOptions.failFn && ((typeof ajaxOptions.failFn) == "function")) {
                    ajaxOptions.failFn(r);
                } else {
                    Dialog.alert('后台程序出错，请联系管理员！');
                }
            }
        });
    },
    /**
     * ajax GET 请求
     * @param url
     * @param data
     * @param successFn
     * @param options
     */
    ajaxGET: function (url, data, successFn, options) {
        this.ajax('GET', url, data, successFn, options);
    },
    /**
     * ajax POST 请求
     * @param url
     * @param data
     * @param successFn
     * @param options
     */
    ajaxPOST: function (url, data, successFn, options) {
        this.ajax('POST',url, data, successFn, options);
    }
};

var JSTree = {
    loading: function (jsTree, url, callback, options) {
        options = $.extend({
            multiple: false
        }, options);

        var jsTreeObj = $(jsTree);
        //清空树
        jsTreeObj.data('jstree', false).empty();

        //重新加载
        jsTreeObj.jstree({
            plugins: ["wholerow", "json_data"],
            core: {
                data: {
                    dataType: "json",
                    url: function (node) {
                        var _url = url.replace(/\{nodeId\}/g, (node && node.id == '#' ? '0' : node.id));

                        return _url + '&' + $('.tree-param').serialize();
                    }
                },
                multiple: options.multiple
            }
        }).on("dblclick.jstree", function () {
            var tree = $.jstree.reference(jsTree);
            var node = tree.get_selected(true);
            if (callback) {
                callback(tree, node);
            }
        });
    }
};

/**
 * ztree
 * @type {{init: ZTree.init}}
 */
var ZTree = {
    init: function (treeId, url, options) {
        options = $.extend({
            postData: {},
            clickTree: function (treeId, treeNode, clickFlag) {
            },
            getFirstNode: function (treeNode) {
            },
            dblClickTree: function (event, treeId, treeNode) {

            },
            asyncSuccess: function (){

            },
            check: {
                enable: true
            },
            data: {
                key: {
                    name: "text"
                },
                simpleData: {
                    enable: true,
                    idKey: "id",
                    pIdKey: "pId",
                    rootPId: "0"
                }
            }
        }, options);

        var setting = {
             check: options.check,
             view: options.view,
             data: options.data,
             callback: {
                 beforeClick: function (treeId, treeNode, clickFlag) {
                    options.clickTree(treeId, treeNode, clickFlag);
                 }
                 ,
                 onDblClick: function (event, treeId, treeNode) {
                    options.dblClickTree(event, treeId, treeNode);
                 }
                 ,onAsyncSuccess: function (event, treeId, treeNode) {
                     options.asyncSuccess(event, treeId, treeNode);
                 }
             }
        }
        if (typeof (url) == 'string') {
            Page.ajaxPOST(url, options.postData, function (data) {
                $.fn.zTree.init($("#" + treeId), setting, data.result);
                var zTree = $.fn.zTree.getZTreeObj(treeId);
                var rootnodes = zTree.getNodes();
                if (rootnodes[0] == undefined) {
                    return;
                }
                options.getFirstNode(rootnodes[0]);
                options.asyncSuccess()
            });
        }

        var operation = {
            add: function (nodes, pId, newNode, zTree) {
                $.each(nodes, function (i, obj) {
                    if (obj.id == pId) {
                        zTree.addNodes(nodes[i], newNode);
                        $.each(nodes[i].children, function (i, obj) {
                            if (obj.id == newNode.id) {
                                zTree.selectNode(obj);
                            }
                        })
                        options.clickTree(null, newNode, null);
                        return;
                    }
                    if (undefined != nodes[i].children) {
                        operation.add(nodes[i].children, pId, newNode, zTree);
                    }
                })
            },
            update: function (nodes, id, currentNode, zTree) {
                $.each(nodes, function (i, obj) {
                    if (obj.id == id) {
                        var node = nodes[i];
                        node.text = currentNode.text;
                        node.pId = currentNode.pId;
                        zTree.updateNode(node);
                        zTree.selectNode(node);
                        options.clickTree(null, node, null);
                        return;
                    }
                    if (undefined != nodes[i].children) {
                        operation.update(nodes[i].children, id, currentNode, zTree);
                    }
                })
            },
            remove: function (nodes, id, newNode, zTree) {
                for (var i = 0; i < nodes.length; i++){
                    if (nodes[i].id == id){
                        zTree.removeNode(nodes[i]);
                        // options.clickTree(null, nodes[i], null);
                        return;
                    }
                    if (nodes[i].children) {
                        operation.remove(nodes[i].children, id, newNode, zTree);
                    }
                }
            }
        };

        return {
            getOptions: options,
            getTreeObj: function () {
                return $.fn.zTree.getZTreeObj(treeId);
            },
            selectNodeIndex: function (index) {
                if (index >= 0) {
                    var nodes = this.getTreeObj().getNodes();
                    this.getTreeObj().checkNode(nodes[index]);
                }
            },
            getSelected: function (field) { // 指定返回指定field的值,，如 'id'
                var result = [];
                var selectedNodes = this.getTreeObj().getSelectedNodes();
                for (var i = 0; i < selectedNodes.length; i++) {
                    result.push(field ? selectedNodes[i][field] : selectedNodes[i])
                }
                return result;
            },
            addNode: function (newNode) {
                operation.add(this.getTreeObj().getNodes(), newNode.pId, newNode, this.getTreeObj());
            },
            updateTreeNode: function (currentNode) {
                operation.update(this.getTreeObj().getNodes(), currentNode.id, currentNode, this.getTreeObj());
            },
            removeNode: function (newNode) {//例子:vendor/list.jsp[192]
                operation.remove(this.getTreeObj().getNodes(), newNode.id, newNode, this.getTreeObj());
            },
        };
    }
};

/**
 * 查询类
 */
var Searcher = {
    /**
     * 创建查询器（根据规范来限制表单元素）
     * <pre>
     *   查询表单ID：jqGrid + 'Form'
     *   查询按钮ID：jqGrid + 'Button'
     *   分页条ID： jqGrid + 'Pager'
     * </pre>
     * @param jqGrid 必须。jqGrid对象
     * @param colModel 必须。展示的列表定义
     * @param options 可选。其他jqGrid参数, 如果为false，则不主动加载数据
     * @returns {{options, query: searcher.query, getSelectedRows: searcher.getSelectedRows}}
     */
    create: function (jqGrid, colModel, options) {
        var jqGridObject = $(jqGrid);
        var jqGridId = jqGridObject.attr('id');
        var searchForm = $('#' + jqGridId + 'Form');
        var searchButton = searchForm.find(':submit');
        var searchUrl = searchForm.attr('action');
        var rawData = null;
        var jqGridOptions = $.extend({
            url: searchUrl,
            mtype: 'POST',
            datatype: "json",
            height: 'auto',
            autowidth: false,
            shrinkToFit: true,
            rownumbers: true,//展现行号
            rowNum: 10,
            rowList: [10, 20, 30],
            loadtext: "数据加载中，请稍等。。。",
            jsonReader: {
            root:"result.list", page:"result.currPage", total:"result.totalPage", //很重要 定义了 后台分页参数的名字。
            records:"result.totalCount", repeatitems:false
            },
            colModel: colModel,
            pager: "#" + jqGridId + "Pager",
            viewrecords: true,
            caption: jqGridObject.attr('title'),
            multiselect: true, // 复选框
            hidegrid: false,
            postData: searchForm.serializeObject(),
            loadError: function () {
                Dialog.alert('数据加载失败！');
            },
            serializeGridData: function (data) {
                return data;
            },
            beforeProcessing: function (data) {
                if (data.code == '0') {
                    rawData = data;
                    if (data.result.rows == undefined) {
                        data.rows = data.result;
                    } else {
                        for (var k in data.result) {
                            data[k] = data.result[k];
                        }
                    }
                    return true;
                } else {
                    Dialog.errorMsg(data.msg);
                    if (data.result == undefined) {
                        data.rows = [];
                    }
                    return true;
                }
            },
            footerConfig: null
        }, options);

        // ------------------- 自定义参数设置 开始---------------------
        // 是否主动加载数据
        if (options === false || jqGridOptions.firstLoad === false) { // 不主动加载数据
            jqGridOptions.datatype = 'local';
        }
        // 设置Footer，例如：footerConfig: {'saleCompanyName': '已选中 [{R.count}] 条','invAmount': 'sum()', 'invTax': 'sum()', 'invTotalAmount': 'sum()'}
        if(jqGridOptions.footerConfig && typeof (jqGridOptions.footerConfig) === 'object') {
            jqGridOptions.footerrow = true;
            jqGridOptions.refreshFooter = function () {
                // 处理结果
                var R = {
                    /** 总数 */
                    count: 0,
                    /** 选中的ID */
                    selectedIds: jqGridObject.jqGrid("getGridParam", "selarrrow"),
                    /**
                     * 根据模板计算值
                     * @param object 数据
                     * @param name 字段名称
                     * @param express 模板表达式
                     * @returns {*}
                     */
                    _evalValue: function(object, name, express) {
                        var R = this, I = object;
                        if(express === 'sum()'){                     // 固定值：sum()
                            return addCalc(R[name] || 0, object[name] || 0, 2);
                        } else if(typeof (express) === 'function') { // 函数：functionName(字段名，数据，当前结果)
                            return express(name, object, R);
                        } else if(typeof (express) === 'string') {   // 模板字符串：“已选择 {R.count} 行”
                            var pattern = /\{(.*?)\}/gi, result;
                            while ((result = pattern.exec(express)) != null)  {
                                express = express.replace(result[0], eval(result[1]));
                            }
                            return express;
                        } else {
                            return express;
                        }
                    }
                };
                // 计算默认值
                for(var name in jqGridOptions.footerConfig){
                    R[name] = R._evalValue({}, name, jqGridOptions.footerConfig[name]);
                }
                // 计算最终的值
                for(var i = 0; i < R.selectedIds.length; i++){
                    // 统计总数
                    R.count = R.count + 1;
                    // 行数据
                    var item = jqGridObject.jqGrid("getRowData", R.selectedIds[i]);
                    // 计算
                    for(var name in jqGridOptions.footerConfig){
                        R[name] = R._evalValue(item, name, jqGridOptions.footerConfig[name]);
                    }
                }
                // 刷新Footer
                jqGridObject.footerData('set', R);
            };
            jqGridOptions._onPaging = clone(jqGridOptions.onPaging);
            jqGridOptions._onSelectRow = clone(jqGridOptions.onSelectRow);
            jqGridOptions._onSelectAll = clone(jqGridOptions.onSelectAll);
            jqGridOptions._loadBeforeSend = clone(jqGridOptions.loadBeforeSend);
            jqGridOptions.onPaging = function () {
                jqGridOptions._onPaging && jqGridOptions._onPaging();
                jqGridOptions.refreshFooter();
            };
            jqGridOptions.onSelectRow = function () {
                jqGridOptions._onSelectRow && jqGridOptions._onSelectRow();
                jqGridOptions.refreshFooter();
            };
            jqGridOptions.onSelectAll = function () {
                jqGridOptions._onSelectAll && jqGridOptions._onSelectAll();
                jqGridOptions.refreshFooter();
            };
            jqGridOptions.loadBeforeSend = function () {
                jqGridOptions._loadBeforeSend && jqGridOptions._loadBeforeSend();
                jqGridOptions.refreshFooter();
            };
        }
        // ------------------- 自定义参数设置 结束---------------------
        // 初始化表格
        jqGridObject.jqGrid(jqGridOptions);//.navGrid("#" + jqGridId + "Pager", {edit: false, add: false, del: false});

        // 设置基本函数
        var searcher = {
            getRawData: function (id) {
                var rows = rawData.rows ? rawData.rows : rawData;
                if (id) {
                    for (var i = 0; i < rows.length; i++) {
                        if (rows[i]['id'] == id) {
                            return rows[i];
                        }
                    }
                    return null;
                }
                return rows;
            },
            jqGrid: jqGridObject,
            options: jqGridOptions,
            query: function (currentPage) {
                if(searchForm.valid && !searchForm.valid()) {
                    return false;
                }
                var params = {
                    datatype: 'json',
                    postData: searchForm.serializeObject()
                };
                if(!currentPage) params.page = 1;
                jqGridObject.jqGrid('setGridParam', params).trigger("reloadGrid");
            },
            getSelectedRows: function (field) { // 可以只获取指定字段的值
                var rowData = [];
                var rowIds = jqGridObject.jqGrid("getGridParam", "selarrrow");
                for (var i = 0; i < rowIds.length; i++) {
                    var item = jqGridObject.jqGrid("getRowData", rowIds[i]);
                    rowData.push(typeof field === 'string' ? item[field] : item);
                }
                return rowData;
            },
            getSelectedOriginalRows: function (field) {//可以获取指定字段的原始值,例子参考views/masterdata/vendoruser/edit[145-148]
                var rowData = [];
                var rowIds = jqGridObject.jqGrid("getGridParam", "selarrrow");
                for (var i = 0; i < rowIds.length; i++) {
                    var item = this.getRawData(rowIds[i]);
                    rowData.push(typeof field === 'string' ? item[field] : item);
                }
                return rowData;
            },
            callback: function (msg) {
                return function (msg, searcher) {
                    Dialog.msg(msg, searcher.query);
                }
            },
            refreshFooter: function () {
                this.options.refreshFooter && this.options.refreshFooter();
            }
            // 其他常用函数
        };

        // 取消form的默认提交事件
        searchForm.onsubmit = function () {
            return false;
        };
        // 绑定查询按钮
        searchButton.click(function () {
            searcher.query();
            return false;
        });
        // 加载尾行
        searcher.refreshFooter();

        // 返回jqGrid句柄
        return searcher;
    },

    createBS: function (bsTable, colModel, options) {
    	for(var i=0; i < colModel.length; i++) {
    		if(colModel[i].cellStyle == null || colModel[i].cellStyle == undefined) {
    			colModel[i].cellStyle = {css:{"overflow": "hidden", "text-overflow": "ellipsis", "white-space": "nowrap"}};
    		}
    		if(colModel[i].align == null || colModel[i].align == undefined) {
    			colModel[i].align = "center";
    		}
    		if(colModel[i].valign == null || colModel[i].valign == undefined) {
    			colModel[i].valign = "middle";
    		}
    	}
        var bsTableObject = $(bsTable);
        var searchForm = $(bsTable + 'Form');
        var searchButton = $(bsTable+"SearchBtn");
        var searchUrl = searchForm.attr('action');
        var method = searchForm.attr('method');
        var rawData = null;
        var firstLoad = true;
        if (options != undefined) {
            if (!Common.isEmpty(options.firstLoad)) {
                firstLoad = options.firstLoad;
            }
        }
        if (!firstLoad) {
            searchUrl = "";
        }
        var bsTableOptions = $.extend({
            contentType: "application/x-www-form-urlencoded",
            url: searchUrl,				//请求地址
            method: 'post',		//ajax方式,post还是get
            ajaxOptions: {				//ajax请求的附带参数
                data: searchForm.serializeObject()
            },
            toolbar: bsTable+"ToolBar",//顶部工具条
            striped: true,     			//是否显示行间隔色
            cache: false,      			//是否使用缓存,默认为true
            pagination: true,     		//是否显示分页（*）
            sortable: true,      		//是否启用排序
            sortOrder: "desc",     		//排序方式
            pageNumber: 1,      		//初始化加载第一页，默认第一页
            pageSize: 15,      			//每页的记录行数（*）
            pageList: [15, 50, 100, 500],  	//可供选择的每页的行数（*）
            queryParamsType: 'limit', 	//默认值为 'limit' ,在默认情况下 传给服务端的参数为：offset,limit,sort
            queryParams: function (params) { //设置查询参数
                var extParam = searchForm.serializeObject();
                var param = {
                    limit: params.limit,                         //页面大小
                    page: (params.offset / params.limit) + 1,   //页码
                    sidx: params.sort,  //排序列名
                    order: params.order //排位命令（desc，asc）
                };
                return subJson(extParam, param);
            }, // 向后台传递的自定义参数
            sidePagination: 'server',   //分页方式：client客户端分页，server服务端分页（*）
            search: false,      		//是否显示表格搜索，此搜索是客户端搜索，不会进服务端
            strictSearch: true,			//设置为 true启用 全匹配搜索，否则为模糊搜索
            showColumns: true,     		//是否显示所有的列
            showRefresh: true,     		//是否显示刷新按钮
            minimumCountColumns: 2,    	//最少允许的列数
            clickToSelect: false,    	//是否启用点击选中行
            searchOnEnterKey: true,		//设置为 true时，按回车触发搜索方法，否则自动触发搜索方法
            showExport: true,           //是否显示导出
            exportDataType: "basic",    //basic', 'all', 'selected'
            exportTypes: ['excel'],
            columns: colModel,		//列数组
            pagination: true,			//是否显示分页条
            iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome)
            icons: {
                paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',
                paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up',
                refresh: 'glyphicon-refresh icon-refresh',
                toggle: 'glyphicon-list-alt icon-list-alt',
                columns: 'glyphicon-th icon-th',
                detailOpen: 'glyphicon-plus icon-plus',
                detailClose: 'glyphicon-minus icon-minus'
            },
            iconSize: 'outline',
            responseHandler: function(res) {// 处理后台返回数据格式
            	if(res.code == 0 || res.code == 200) {
                    return {
                        "total": res.result.totalCount,//总条数
                        "rows": res.result.list   //数据
                    };
            	}
            	return res;
            },
            onLoadError: function(){  //加载失败时执行
                layer.msg("加载数据失败", {time : 1500, icon : 2});
            },
            onLoadSuccess: function(res){  //加载成功时执行
            	if(res.code != undefined && res.code != 0 && res.code != 200) {
            		layer.msg("加载数据失败", {time : 1500, icon : 2});
            	}
            }
        }, options);

        bsTableObject.bootstrapTable(bsTableOptions);

        // 取消form的默认提交事件
        searchForm.submit(function () {
            return false;
        });

        var searchParamLi = searchForm.find("li");
        //绑定高级搜索事件
        $(bsTable + "AdvancedSearch").on("click", function () {
            $(bsTable + "AdvancedSearch").find("i").each(function (i, e) {
                if ($(e).hasClass("fa-caret-down")) {
                    $(e).removeClass("fa-caret-down").addClass("fa-caret-up");
                } else {
                    $(e).removeClass("fa-caret-up").addClass("fa-caret-down");
                }
            });
            searchForm.find("li").each(function (i, e) {
                if (i >= 8 && i != searchParamLi.length - 1) {
                    if (!$(e).is(':visible')) {　　//如果是隐藏的则显示，否则隐藏
                        $(e).show();
                    } else {
                        $(e).hide();
                    }
                }
            });
        });
        // 隐藏高级搜索条件
        if (searchParamLi.length > 9) {
            $(bsTable + "AdvancedSearch").show();

            // 从第9个条件开始隐藏
            searchForm.find("li").each(function(i,e){
                if (i >= 8 && i != searchParamLi.length-1) {
                    //$(e).hide();
                }
            });
        }

        // 设置基本函数
        var bsSearcher = {
            getRawData: function () {
                return bsTableObject.bootstrapTable('getSelections');
            },
            refresh: function (params) {
                if (params != undefined) {
                    bsTableObject.bootstrapTable('refresh', subJson(params, searchForm.serializeObject()));
                } else{
                    bsTableObject.bootstrapTable('refresh');
                }
            },
            getData: function (params) {
                if (params != undefined) {
                    bsTableObject.bootstrapTable('refresh', params);
                } else{
                	bsTableObject.bootstrapTable('refresh');
                }
            },     
            getSelectedRows: function (field) { // 可以只获取指定字段的值
                var rowData = [];
                var rows = bsTableObject.bootstrapTable('getSelections');
                for (var i = 0; i < rows.length; i++) {
                    rowData.push(typeof field === 'string' ? rows[i][field] : '');
                }
                return rowData;
            },
            refreshOptions: function (newOptions) {
                bsTableObject.bootstrapTable('refreshOptions', newOptions);

            },
            showLoading: function () {
                bsTableObject.bootstrapTable('showLoading');
            }
        };

        // 绑定查询按钮
        if (!Common.isEmpty(searchUrl)) {
            searchButton.click(function (resetOption) {
                bsSearcher.refresh();
                return false;
            });
        }
        // 返回bsTable句柄
        return bsSearcher;
    }
};

var TREE_GRID = {
	    init: function (table, options) {
	        var treeOptions = $.extend({
	            treeColumn: 1,
	            method: 'get',
	            //url: "",
	            singleSelect: true,//单行选择
	            clickToSelect: true,//点击行时自动选择
	            striped: false,//是否显示行间隔色
	            //treeId: "id",//定义关键字段来标识树节点
	            //treeField: "txt",//定义树节点字段
	            //treeParentId: "typeId", //定义父级ID字段
	            treeRootLevel: 0,//根节点序号
	            treeCollapseAll: true,//是否全部折叠，默认折叠
	            cascadeCheck: false,//是否层叠选中状态(选中父级，子级全部选中) true=层叠选中，需要singleSelect: false；false=不是层叠选中
	            //uniqueId: "id", //每一行的唯一标识，一般为主键列
	            collapseIcon: "glyphicon glyphicon-triangle-right",//折叠样式
	            expandIcon: "glyphicon glyphicon-triangle-bottom",//展开样式
	            lastIcon: "",//叶子节点样式
	            onLoadSuccess: function(data) {},
	            onResetView: function() {}
	        }, options);
	        
	        var $table = $("#"+table);
	        TREE_GRID.table = $table;
	        
	        return $table.bootstrapTable({
	            url: treeOptions.url,
	            striped:treeOptions.striped,
	            treeColumn: treeOptions.treeColumn,
	            method: treeOptions.method,
	            singleSelect: treeOptions.singleSelect,//单行选择
	            clickToSelect: treeOptions.clickToSelect,//点击行时自动选择
	            treeView: true,//是否显示树形视图
	            treeId: treeOptions.treeId,//定义关键字段来标识树节点
	            treeField: treeOptions.treeField,//定义树节点字段
	            treeRootLevel: treeOptions.treeRootLevel,//根节点序号
	            treeParentId: treeOptions.treeParentId, //定义父级ID字段
	            treeCollapseAll: treeOptions.treeCollapseAll,//是否全部折叠，默认折叠
	            cascadeCheck: treeOptions.cascadeCheck,//是否层叠选中状态(选中父级，子级全部选中) true=层叠选中，需要singleSelect: false；false=不是层叠选中
	            uniqueId: treeOptions.uniqueId, //每一行的唯一标识，一般为主键列
	            collapseIcon: treeOptions.collapseIcon,//折叠样式
	            expandIcon: treeOptions.expandIcon,//展开样式
	            lastIcon: treeOptions.lastIcon,//叶子节点样式
	            onLoadSuccess: treeOptions.onLoadSuccess,
	            onResetView: treeOptions.onResetView,
	            columns: treeOptions.columns
	        });
	    },
	    refresh: function (form) {
	    	if(form) {
	    		this.search(form);
	    	} else {
	    		TREE_GRID.table.bootstrapTable('refresh');
	    	}
	    },
	    // 条件查询
	    search: function(form) {
	        var params = {};
	        $.each($("#" + form).serializeArray(), function(i, field) {
	            params[field.name] = field.value;
	        });
	        TREE_GRID.table.bootstrapTable('refresh', {query: params});
	    }
};

var TREE_TABLE = {
    options: {},
    table: {},
    init: function (table, options) {
        var treeOptions = $.extend({
            striped:false,
            sidePagenation: 'server',
            treeColumn: 1
        }, options);
        
        TREE_TABLE.options = treeOptions;

        var $table = $("#"+table);
        TREE_TABLE.table = $table;
        
        return $table.bootstrapTable({
            url: treeOptions.url,
            idField: treeOptions.idField,
            striped:treeOptions.striped,
            sidePagenation: treeOptions.sidePagenation,
            columns: treeOptions.columns,
            treeShowField: treeOptions.treeShowField,
            parentIdField: treeOptions.parentId,
            queryParams : options.params,
            onLoadSuccess: function(data) {
            	if(treeOptions.success) {treeOptions.success();}
                $table.treegrid({
                    initialState: 'collapsed',//收缩
                    treeColumn: treeOptions.treeColumn,//指明第几列数据改为树形
                    expanderExpandedClass: 'glyphicon glyphicon-triangle-bottom',
                    expanderCollapsedClass: 'glyphicon glyphicon-triangle-right',
                    onChange: function() {
                        $table.bootstrapTable('resetWidth');
                    }
                });
            }
        });
    },
    refresh: function (form) {
    	if(form) {
    		this.search(form);
    	} else {
    		TREE_TABLE.table.bootstrapTable('refresh');
    	}
    },
    // 条件查询
    search: function(form) {
        var params = {};
        $.each($("#" + form).serializeArray(), function(i, field) {
            params[field.name] = field.value;
        });
        TREE_TABLE.table.bootstrapTable('refresh', {query: params});
    }
}

/**
 * 格式化类
 */
var Formatter = {
    Date: function (value, row, index) {
        return isNaN(value) ? value : $.formatDate("yyyy-MM-dd", new Date(value));
    },
    Currency: function (value, row, index) {
        return formatCurrency(value);
    },
    TaxRate: function (value, row, index) {
        return ((value && value != '' ? value : 0) / 100.0).toFixed(2) + '';
    },
    Price: function (value, row, index) {
        return (((value != undefined && value != '') ? value : 0)/100.0).toFixed(2);
    },
    Amount: function (value, row, index) {
        return formatCurrency(value);//((value && value != '' ? value : 0) * 1).toFixed(2) + '';
    },
    Number: function (value, row, index) {
        return ((value && value != '' ? value : 0) * 1).toFixed(2) + '';
    },
    Remark: function (value, row, index) {
        return '<textarea id="invRemark' + row.id + '" style="display: none">' + value + '</textarea>'
            + '<a href="javascript:void(0);" onclick="clickRemark($(\'#invRemark' + row.id + '\').val())">查看备注</a>';
    },
    LongText: function (length, alertText, showText) {//例子:vendor/list.jsp[103]
        return function (value, options, row) {
            value = value || '';
            if (value == null || value.length <= length) {
                return value;
            }
            var alertText_ = alertText || value;
            var showText_ = showText || '......';
            alertText_ = typeof(alertText_) == 'function' ? alertText_(value, options, row) : alertText_;
            showText_ = typeof(showText_) == 'function' ? showText_(value, options, row) : showText_;
            var html = $('<label onclick="layer.alert(this.title,{shadeClose:true})">' + value.substring(0, length) + showText_ + '</label>');
            html.attr('title', alertText_);
            return html[0].outerHTML;
        };
    },
    showDesc: function (map, defvalue) { //例子:vendor/list.jsp[96,98]
        defvalue = defvalue || '';
        return function (value, options, row) {
            return map[value] ? map[value] : defvalue;
        }
    },
    setDefault: function(defaultStr){
        return function(value, options,row){
            if (value == null || value == "" || value == undefined) {
                return defaultStr;
            } else{
                return value;
            }
        }
    },
    aHref:function(hrefUrl,attr){ //表单指定字段增加a标签跳转 例子：资源维护
        attr = (attr == null) ? "id" : attr;
        return function(value, options, row){
            return "<a href='"+hrefUrl+"?"+attr+"="+row[attr]+"'>"+value+"</a>";
        }
    }
};

var FileInput = {

    init: function(ctrlName, uploadUrl, options, picIdContainer) {
        options = $.extend({
            uploadUrl: uploadUrl,
            uploadAsync:true,
            showUpload: true,//是否显示上传按钮
            showRemove: true,//是否显示删除按钮
            showCaption: true,//是否显示输入框
            rtl: true,
            showPreview:true,
            showCancel:true,
            dropZoneEnabled: false,
            maxFileCount: 10,
            initialPreviewShowDelete:true,
            msgFilesTooMany: "选择上传的文件数量 超过允许的最大数值！",
            previewFileIcon: '<i class="fa fa-file"></i>',
            allowedPreviewTypes: ['image'],
            previewFileIconSettings: {
                'docx': '<i class="fa fa-file-word-o text-primary"></i>',
                'xlsx': '<i class="fa fa-file-excel-o text-success"></i>',
                'pptx': '<i class="fa fa-file-powerpoint-o text-danger"></i>',
                'pdf': '<i class="fa fa-file-pdf-o text-danger"></i>',
                'zip': '<i class="fa fa-file-archive-o text-muted"></i>',
                'sql': '<i class="fa fa-file-word-o text-primary"></i>',
            }
            /*,
            layoutTemplates :{
                actionDelete:'', //去除上传预览的缩略图中的删除图标
                actionUpload:'',//去除上传预览缩略图中的上传图片；
                actionZoom:''  //去除上传预览缩略图中的查看详情预览的缩略图标。

            }*/
        },options);
        var control = $('#' + ctrlName);
        control.fileinput(options);
        if (picIdContainer != '' && picIdContainer != null) {
            control.on("fileuploaded", function (event, res, previewId, index) {
                $("#"+ picIdContainer).val(res.response.picId)
            });
        }
    },
    initPortrait: function (ctrlName, picId) {
        var control = $('#' + ctrlName);
        if (picId != null) {
            var previewArr = [];
            if (!validPositiveInteger(picId)) {
                var picIds = picId.split(",");
                for(var i=0; i< picIds.length;i++) {
                    if (picIds[i] != "" && picIds[i] != null) {
                        var imgContainer = "<img src='" + ctxPath + '/sys/user/getPic/' + picIds[i] + "' class='file-preview-image' alt='图片' title='图片'>";
                        previewArr.push(imgContainer);
                    }
                }
            } else{
                var imgContainer = "<img src='" + ctxPath + '/sys/user/getPic/' + picId + "' class='file-preview-image' alt='图片' title='图片'>";
                previewArr.push(imgContainer);
            }
        }
        //重要，需要更新控件的附加参数内容，以及图片初始化显示
        control.fileinput('refresh', {
            initialPreview: previewArr
        }
    );
}

}

// 通用方法封装处理
var Common =  {
    // 判断字符串是否为空
    isEmpty: function (value) {
        if (value == null || value == undefined || this.trim(value) == "") {
            return true;
        }
        return false;
    },
    // 是否显示数据 为空默认为显示
    visible: function (value) {
        if ($.common.isEmpty(value) || value == true) {
            return true;
        }
        return false;
    },
    // 空格截取
    trim: function (value) {
        if (value == null) {
            return "";
        }
        return value.toString().replace(/(^\s*)|(\s*$)|\r|\n/g, "");
    },
    // 指定随机数返回
    random: function (min, max) {
        return Math.floor((Math.random() * max) + min);
    }
};


$.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

/**
 * 面板的折叠与展开
 * @param id
 */
function dynamicContent(id) {
    $("#"+id).slideToggle(200, function () {
        $(this).prev().find("i").toggleClass('fa-chevron-up').toggleClass('fa-chevron-down');
        if($(this).is(":visible")) {
            $(this).prev().find("span").text("折叠");
        } else{
            $(this).prev().find("span").text("展开");
        }
    });
}

/**
 * 合并两个json对象
 * @param jsonbject1
 * @param jsonbject2
 */
function subJson(jsonbject1, jsonbject2) {
    var resultJsonObject = {};
    for (var attr in jsonbject1) {
        resultJsonObject[attr] = jsonbject1[attr];
    }
    for (var attr in jsonbject2) {
        resultJsonObject[attr] = jsonbject2[attr];
    }
    return resultJsonObject;
}

/**
 * 显示组件
 */
var loading = null;

/**
 * 显示数据处理提示
 */
function ajaxLoading(msg) {
	if(Common.isEmpty(msg)) {
		msg = "操作中……";
	}
	loading = layer.msg(msg, {
		  icon: 16,
		  shade: 0.02,
		  time: 0 //不自动关闭
	});
}
/**
 * 隐藏数据处理提示
 */
function closeAjaxLoading() {
	if(loading != null) {
		layer.close(loading);
		loading = null;
	}
}

/**
 * 动态面板
 * @param id
 */
function dynamicContent(id) {
    $("#"+id).slideToggle(200, function () {
        $(this).prev().find("i").toggleClass('fa-chevron-up').toggleClass('fa-chevron-down');
        if($(this).is(":visible")) {
            $(this).prev().find("span").text("折叠");
        } else{
            $(this).prev().find("span").text("展开");
        }
    });
}